/**  
* Copyright (c) 2008, Noel Lynch All rights reserved. Redistribution and use  
* in source and binary forms, with or without modification, are permitted  
* provided that the following conditions are met: Redistributions of source  
* code must retain the above copyright notice, this list of conditions and the  
* following disclaimer. Redistributions in binary form must reproduce the above  
* copyright notice, this list of conditions and the following disclaimer in the  
* documentation and/or other materials provided with the distribution. Neither  
* the name of Noel Lynch nor the names of contributors may be used to  
* endorse or promote products derived from this software without specific prior  
* written permission. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND 
* CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT  
* NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A  
* PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR  
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,  
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,  
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;  
* OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,  
* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR  
* OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF  
* ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.  
*/
// Nov 26, 2008

package com.sceneworker.monitorpopup;

import java.awt.event.ActionEvent;
import java.util.concurrent.Callable;

import javax.swing.JDialog;
import javax.swing.JMenu;
import javax.swing.tree.TreePath;

import com.jme.bounding.BoundingSphere;
import com.jme.scene.Node;
import com.jme.scene.TriMesh;
import com.jme.scene.lod.AreaClodMesh;
import com.jme.scene.lod.ClodMesh;
import com.jme.util.GameTaskQueueManager;
import com.jme2utils.staticutils.GenericJMEUtils;
import com.jme2utils.staticutils.MeshUtils;
import com.myjavautils.swing.SimpleAlert;
import com.sceneworker.app.globals.SceneWorkerDialogManager;
import com.sceneworker.editors.materialeditor.MaterialEditorPanel;
import com.sceneworker.editors.trimesheditor.ExportTriMeshPanel;
import com.sceneworker.monitorpopup.panels.ViewMeshBuffersPanel;

public class TriMeshMenu extends BaseMenu {

	private static final String VIEW_TEXTURE_COORDS = "View Mesh Buffers";
    private static final String OUTPUT_BUFFERS_CONSOLE = "Output Buffers To Console";
    private static final String CONNECT_COMMON_VERTICES = "Connect Common Vertices";
    private static final String CALCULATE_NORMALS_FROM_VERTICES = "Calculate Normals from Vertices";
    private static final String MATERIAL_EDITOR = "Material Editor...";
	private static final String EXPORT_TRI_MESH_ONLY = "Export TriMesh Only";
	private static final String CONVERT_TO_CLOD_MESH = "Convert To Clod Mesh";
	private static final String CONVERT_TO_AREA_CLOD_MESH = "Convert To Area Clod Mesh";
	
	
	private		TriMesh		mcl_mesh;
	private		Node		mcl_parNode;
	
	public TriMeshMenu(TreePath cl_selectedPath, SceneWorkerPopUp cl_menu) {
		super(cl_menu);
		
		mcl_mesh = (TriMesh)cl_selectedPath.getLastPathComponent();
		
		if(mcl_mesh instanceof AreaClodMesh) {
			return;
		}
		
		if(cl_selectedPath.getParentPath() != null) {
			if(cl_selectedPath.getParentPath().getLastPathComponent() instanceof Node) {
				mcl_parNode = (Node)cl_selectedPath.getParentPath().getLastPathComponent();
			}
		}
		
		buildMenu();
	}

	@Override
	public void actionPerformed(ActionEvent cl_e) {
		
		if(cl_e.getActionCommand().equals(CONVERT_TO_AREA_CLOD_MESH)) {
			if(mcl_parNode == null) {
				SimpleAlert.doAlert("Cannot convert this mesh to a clod mesh. Parent is null.", null);
			}
			
			GameTaskQueueManager.getManager().update(new Callable<Void>() {
				
				public Void call() throws Exception {
					AreaClodMesh		lcl_clod = new AreaClodMesh(mcl_mesh.getName() + "AreaCLOD", mcl_mesh, null);
					lcl_clod.setLocalTranslation(mcl_mesh.getLocalTranslation());
					lcl_clod.setLocalRotation(mcl_mesh.getLocalRotation());
					lcl_clod.setLocalScale(mcl_mesh.getLocalScale());
					mcl_mesh.removeFromParent();
					
					mcl_parNode.attachChild(lcl_clod);
					lcl_clod.setModelBound(new BoundingSphere());
					lcl_clod.updateModelBound();
					lcl_clod.updateRenderState();
					
					mcl_parNode.updateGeometricState(0, true);
					mcl_parNode.updateModelBound();
					mcl_parNode.updateRenderState();
					return null;
				}
				
			});
		}
		
		if(cl_e.getActionCommand().equals(CONVERT_TO_CLOD_MESH)) {
			if(mcl_parNode == null) {
				SimpleAlert.doAlert("Cannot convert this mesh to a clod mesh. Parent is null.", null);
			}
			
			GameTaskQueueManager.getManager().update(new Callable<Void>() {

				public Void call() throws Exception {
					ClodMesh			lcl_clod = new ClodMesh(mcl_mesh.getName() + "CLOD", mcl_mesh, null);
					lcl_clod.setLocalTranslation(mcl_mesh.getLocalTranslation());
					lcl_clod.setLocalRotation(mcl_mesh.getLocalRotation());
					lcl_clod.setLocalScale(mcl_mesh.getLocalScale());
					mcl_mesh.removeFromParent();
					
					mcl_parNode.attachChild(lcl_clod);
					lcl_clod.setModelBound(new BoundingSphere());
					lcl_clod.updateModelBound();
					lcl_clod.updateRenderState();
					
					mcl_parNode.updateGeometricState(0, true);
					mcl_parNode.updateModelBound();
					mcl_parNode.updateRenderState();
					return null;
				}
				
			});
		}
		
		if(cl_e.getActionCommand().equals(CALCULATE_NORMALS_FROM_VERTICES)) {
		  GameTaskQueueManager.getManager().update(new Callable<Void>() {
            public Void call() throws Exception {
                MeshUtils.forcedRecalculateNormals(mcl_mesh);
                SimpleAlert.doAlert("Normals calculated", null);
                return null;
            }
		      
		  }); 
		}
		
		if(cl_e.getActionCommand().equals(CONNECT_COMMON_VERTICES)) {
	          GameTaskQueueManager.getManager().update(new Callable<Void>() {
	            public Void call() throws Exception {
	                MeshUtils.smoothMesh(mcl_mesh);
	                SimpleAlert.doAlert("Mesh reconnected", null);
	                return null;
	            }
	              
	          }); 
	    }
		
		if(cl_e.getActionCommand().equals(OUTPUT_BUFFERS_CONSOLE)) {
	          GameTaskQueueManager.getManager().update(new Callable<Void>() {
	            public Void call() throws Exception {
	                GenericJMEUtils.dumpMeshBuffersToConsole(mcl_mesh);
	                return null;
	            }
	              
	          }); 
	        }
		
		if(cl_e.getActionCommand().equals(EXPORT_TRI_MESH_ONLY)) {
			JDialog		lcl_dlg = SceneWorkerDialogManager.inst().makeADialog(SceneWorkerDialogManager.EXPORT_TRI_MESH_DIALOG);
			ExportTriMeshPanel		lcl_panel = new ExportTriMeshPanel(lcl_dlg, mcl_mesh);
			lcl_dlg.add(lcl_panel);
			lcl_dlg.setVisible(true);
			return;
		}
		
		if(cl_e.getActionCommand().equals(MATERIAL_EDITOR)) {
			JDialog		lcl_dlg = SceneWorkerDialogManager.inst().makeADialog(SceneWorkerDialogManager.MATERIAL_EDITOR_DIALOG);
			MaterialEditorPanel		lcl_panel = new MaterialEditorPanel(mcl_mesh, lcl_dlg);
			lcl_dlg.add(lcl_panel);
			lcl_dlg.setVisible(true);
			return;
		}
		
		if(cl_e.getActionCommand().equals(VIEW_TEXTURE_COORDS)) {
		    /*TextureState        lcl_ts = (TextureState)mcl_mesh.states[RenderState.StateType.Texture.ordinal()];
	        
	        if(lcl_ts == null) {
	            return;
	        }
	        
	        if(lcl_ts.getNumberOfSetTextures() == 0) {
	            return;
	        }*/
	        
            JDialog     lcl_dlg = SceneWorkerDialogManager.inst().makeADialog(SceneWorkerDialogManager.TEXTURE_COORDINATE_VIEWER);
            ViewMeshBuffersPanel     lcl_panel = new ViewMeshBuffersPanel(mcl_mesh, lcl_dlg);
            lcl_dlg.add(lcl_panel);
            lcl_dlg.pack();
            lcl_dlg.setVisible(true);
            return;
        }
	}

	@Override
	protected void buildMenu() {
		mcl_menu.addSeparator();
		
		JMenu			lcl_operationsMenu = new JMenu("Operations...");
		
		if(mcl_parNode != null) {
			lcl_operationsMenu.add(buildAMenuItem(CONVERT_TO_CLOD_MESH));
			lcl_operationsMenu.add(buildAMenuItem(CONVERT_TO_AREA_CLOD_MESH));
		}
		
		lcl_operationsMenu.add(buildAMenuItem(EXPORT_TRI_MESH_ONLY));
		lcl_operationsMenu.add(buildAMenuItem(MATERIAL_EDITOR));
		lcl_operationsMenu.add(buildAMenuItem(CALCULATE_NORMALS_FROM_VERTICES));
		lcl_operationsMenu.add(buildAMenuItem(CONNECT_COMMON_VERTICES));
		lcl_operationsMenu.add(buildAMenuItem(VIEW_TEXTURE_COORDS));
		lcl_operationsMenu.add(buildAMenuItem(OUTPUT_BUFFERS_CONSOLE));
		
		mcl_menu.add(lcl_operationsMenu);
	}

}
